package mybatis.generator.plugin.codegen.xmlmapper;

import mybatis.generator.plugin.common.Common;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.dom.OutputUtilities;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.codegen.mybatis3.ListUtilities;
import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities;
import org.mybatis.generator.codegen.mybatis3.xmlmapper.elements.AbstractXmlElementGenerator;
import org.mybatis.generator.internal.util.StringUtility;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description: mysql 批量插入
 * @Author: wanghanrui
 */
public class InsertBatchElementMysqlGenerator extends AbstractXmlElementGenerator {
    @Override
    public void addElements(XmlElement parentElement) {
        XmlElement insertElement = new XmlElement("insert");
        insertElement.addAttribute(new Attribute("id", Common.INSERTBATCH));

        StringBuilder sb = new StringBuilder();

        sb.append("insert into ");
        sb.append(introspectedTable.getFullyQualifiedTableNameAtRuntime());
        sb.append(" (");


        XmlElement foreachElement = new XmlElement("foreach");
        foreachElement.addAttribute(new Attribute("collection", "list"));
        foreachElement.addAttribute(new Attribute("item", "item"));
        foreachElement.addAttribute(new Attribute("index", "index"));
        foreachElement.addAttribute(new Attribute("separator", ","));


        StringBuilder valuesClause = new StringBuilder();
        valuesClause.append('(');
        List<String> valuesClauses = new ArrayList();
        List<IntrospectedColumn> columns =
                ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns());
        for (int i = 0; i < columns.size(); i++) {
            IntrospectedColumn introspectedColumn = columns.get(i);

            sb.append(MyBatis3FormattingUtilities
                    .getEscapedColumnName(introspectedColumn));

            valuesClause.append(getParameterClause(introspectedColumn, "item", null));
            if (i + 1 < columns.size()) {
                sb.append(", ");
                valuesClause.append(", ");
            }
            if (valuesClause.length() > 80) {
                insertElement.addElement(new TextElement(sb.toString()));
                sb.setLength(0);
                OutputUtilities.xmlIndent(sb, 1);

                valuesClauses.add(valuesClause.toString());
                valuesClause.setLength(0);
                OutputUtilities.xmlIndent(valuesClause, 1);
            }
        }
        sb.append(") values");
        insertElement.addElement(new TextElement(sb.toString()));

        valuesClause.append(")");
        valuesClauses.add(valuesClause.toString());

        for (String clause : valuesClauses) {
            foreachElement.addElement(new TextElement(clause));
        }
        insertElement.addElement(foreachElement);
        parentElement.addElement(insertElement);

    }

    public static String getParameterClause(IntrospectedColumn introspectedColumn, String item, String prefix) {
        StringBuilder sb = new StringBuilder();
        sb.append("#{");
        sb.append(item + '.' + introspectedColumn.getJavaProperty(prefix));
        sb.append(",jdbcType=");
        sb.append(introspectedColumn.getJdbcTypeName());
        if (StringUtility.stringHasValue(introspectedColumn.getTypeHandler())) {
            sb.append(",typeHandler=");
            sb.append(introspectedColumn.getTypeHandler());
        }

        sb.append('}');
        return sb.toString();
    }
}
